using System;
using System.Collections.ObjectModel;
using BenjaminSchroeter.Dsl.CompartmentMapping;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams.GraphObject;

namespace BenjaminSchroeter.CompartmentMapping
{
	#region Code for ConnectionBuilder 'Parent1ReferencesParent2'
    [RuleOn(typeof(Entry1), FireTime = TimeToFire.LocalCommit)]
    [RuleOn(typeof(Entry2), FireTime = TimeToFire.LocalCommit)]
    public class SourceOrTargetOfParent1ReferencesParent2DeletingRule : CompartmentEntryDeletingRuleBase<Parent1, Entry1, Parent1ReferencesParent2, Parent2, Entry2>
    {
        protected override CompartmentMappingBuilderBase<Parent1, Entry1, Parent1ReferencesParent2, Parent2, Entry2> GetBuilderInstance()
        {
            return Parent1ReferencesParent2Builder.builder;
        }
    }

    public class Parent1ReferencesParent2Router : CompartmentMappingRouterBase<Parent1, Entry1, Parent1ReferencesParent2, Parent2, Entry2>
    {
        protected override CompartmentMappingBuilderBase<Parent1, Entry1, Parent1ReferencesParent2, Parent2, Entry2> GetBuilderInstance()
        {
            return Parent1ReferencesParent2Builder.builder;
        }
    }

    public partial class Parent1ReferencesParent2Builder
    {
        internal static readonly Parent1ReferencesParent2BuilderInstance builder = new Parent1ReferencesParent2BuilderInstance();

        public static bool CanAcceptSource(ModelElement candidate)
        {
            return builder.CanAcceptSource(candidate);
        }

        public static bool CanAcceptTarget(ModelElement candidate)
        {
            return builder.CanAcceptTarget(candidate);
        }

        public static bool CanAcceptSourceAndTarget(ModelElement candidateSource, ModelElement candidateTarget)
        {
            return builder.CanAcceptSourceAndTarget(candidateSource, candidateTarget);
        }

        public static ElementLink Connect(ModelElement source, ModelElement target)
        {
            return builder.Connect(source, target);
        }
    }

	// Create this partial class in another file and implement at least the abstract methods!
    public partial class Parent1ReferencesParent2BuilderInstance : CompartmentMappingBuilderBase<Parent1, Entry1, Parent1ReferencesParent2, Parent2, Entry2>
    {
        internal Parent1ReferencesParent2BuilderInstance()
            : base(
                false,		/* connection.Source.AllowHead */
                true,		/* connection.Target.AllowHead */
                true,	/* connection.AllowSelfReference */	
                true		/* connection.AllowsDuplicates */	)
        {
        }
        
        /// <summary>
        /// Gets all links for the Connection used by this ConnectionBuilderInstance.
        /// </summary>
        /// <remarks>Only a static method of the connection instance can get ths links</remarks>
        /// <param name="source">The source.</param>
        /// <param name="target">The target.</param>
        /// <returns></returns>
		protected override ReadOnlyCollection<Parent1ReferencesParent2> GetLinks(Parent1 source, Parent2 target)
        {
			// delegates this call to the static method of the connection class (Parent1ReferencesParent2)
            return Parent1ReferencesParent2.GetLinks(source, target);
        }
    }	
	#endregion

	#region Code for CompartmentShape 'CompartmentShape1'
    partial class CompartmentShape1 : ICompartmentMouseActionTrackable
    {
        private readonly CompartmentMouseTrack mouseTrack = new CompartmentMouseTrack();

        public CompartmentMouseTrack MouseTrack
        {
            get { return mouseTrack; }
        }

        public override void OnShapeInserted()
        {
            mouseTrack.ShapeInserted(this);
            base.OnShapeInserted();
        }
        
        public override void OnAbsoluteBoundsChanged(Microsoft.VisualStudio.Modeling.Diagrams.AbsoluteBoundsChangedEventArgs e)
        {
            CompartmentMappingUtil.RerouteCompartmentMappings(this);
            base.OnAbsoluteBoundsChanged(e);
        }
    }
	#endregion
	#region Code for CompartmentShape 'CompartmentShape2'
    partial class CompartmentShape2 : ICompartmentMouseActionTrackable
    {
        private readonly CompartmentMouseTrack mouseTrack = new CompartmentMouseTrack();

        public CompartmentMouseTrack MouseTrack
        {
            get { return mouseTrack; }
        }

        public override void OnShapeInserted()
        {
            mouseTrack.ShapeInserted(this);
            base.OnShapeInserted();
        }
        
        public override void OnAbsoluteBoundsChanged(Microsoft.VisualStudio.Modeling.Diagrams.AbsoluteBoundsChangedEventArgs e)
        {
            CompartmentMappingUtil.RerouteCompartmentMappings(this);
            base.OnAbsoluteBoundsChanged(e);
        }
    }
	#endregion


	#region Code for Connector 'Connector'
    partial class Connector
    {
        public override void OnInitialize()
        {
            this.FixedFrom = VGFixedCode.Caller;
            this.FixedTo = VGFixedCode.Caller;
            base.OnInitialize();
        }

        public override bool CanManuallyRoute
        {
            get
            {
                return false;
            }
        }
    }
    
    [RuleOn(typeof(Connector), FireTime = TimeToFire.LocalCommit)]
    public class ConnectorAddRule : CompartmentMappingAddRuleBase
    {
    }
	#endregion
}
